package cn.gov.pbc.tims.controller;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

import cn.gov.pbc.tims.entity.Jginfo;
import cn.gov.pbc.tims.entity.User;
import cn.gov.pbc.tims.util.Operator;

@Controller
@RequestMapping("/")
public class CommonController {
	@Autowired
	private Operator operator;
	@Autowired
	private SessionFactory sessionFactory;
	@Autowired
	private ObjectMapper objectMapper;
	private static ArrayNode pbcCache;

	private Session getCurrentSession() {
		return this.sessionFactory.getCurrentSession();
	}

	private List<Jginfo> getChildren(String pbcid) {
		Query<Jginfo> q = this.getCurrentSession()
				.createQuery("from Jginfo where c1Id='A' and pbcId='" + pbcid + "'", Jginfo.class)
				.setCacheable(true);
		List<Jginfo> Jginfos = q.getResultList();
		return Jginfos;
	}

	private boolean hasChildren(String pbcid) {
		return getChildren(pbcid).size() > 0;
	}

	@RequestMapping(value = "getdept", produces = MediaType.APPLICATION_JSON_VALUE)
	public @ResponseBody JsonNode getdept() throws JsonProcessingException, IOException {
		JsonNode jsonNode = objectMapper.readTree(new File(this.getClass().getResource("/json/dept.json").getPath()));
		return jsonNode;
	}

	// 人行单位树当前层的数据，前台点击哪个分支时，获取这个分支数据
	@RequestMapping(value = "getpbc", produces = MediaType.APPLICATION_JSON_VALUE)
	public @ResponseBody ArrayNode getpbc(String id) throws JsonProcessingException, IOException {
		ArrayNode jsonArray = objectMapper.createArrayNode();
		if (id == null)
			id = "A1000111000031";// 这是总行的id
		for (Jginfo Jginfo : getChildren(id)) {
			ObjectNode jsonObject = objectMapper.createObjectNode();
			String id0 = Jginfo.getJgId();
			jsonObject.set("id", objectMapper.convertValue(id0, JsonNode.class));
			jsonObject.set("text", objectMapper.convertValue(Jginfo.getJgName(), JsonNode.class));
			jsonObject.set("state", objectMapper.convertValue(hasChildren(id0) ? "closed" : "open", JsonNode.class));
			jsonArray.add(jsonObject);
		}
		// JsonNode jsonNode=objectMapper.readTree(new
		// File(this.getClass().getResource("/json/pbc.json").getPath()));
		return jsonArray;
	}

	// 获得两层，自己和儿子,只返回两层人行单位数据，为了实现管理员只管理本级和下级管理员
	@RequestMapping(value = "getmysonpbc", produces = MediaType.APPLICATION_JSON_VALUE)
	public @ResponseBody ArrayNode getmysonpbc() throws JsonProcessingException, IOException {
		ArrayNode jsonArray = objectMapper.createArrayNode();
		User op = operator.getUser();
		if (op == null)
			return jsonArray;
		String pbcid = op.getJgId();
		Query<Jginfo> q = this.getCurrentSession()
				.createQuery("from Jginfo where jgId='" + pbcid + "'", Jginfo.class).setCacheable(true);
		Jginfo pbcinfo = q.getSingleResult();
		ObjectNode jsonObject = objectMapper.createObjectNode();
		jsonObject.set("id", objectMapper.convertValue(pbcid, JsonNode.class));
		jsonObject.set("text", objectMapper.convertValue(pbcinfo.getJgName(), JsonNode.class));
		jsonObject.set("state", objectMapper.convertValue("open", JsonNode.class));
		ArrayNode jsonArray1 = objectMapper.createArrayNode();
		for (Jginfo Jginfo : getChildren(pbcid)) {
			ObjectNode jo = objectMapper.createObjectNode();
			String id0 = Jginfo.getJgId();
			jo.set("id", objectMapper.convertValue(id0, JsonNode.class));
			jo.set("text", objectMapper.convertValue(Jginfo.getJgName(), JsonNode.class));
			jo.set("state", objectMapper.convertValue("open", JsonNode.class));
			jsonArray1.add(jo);
		}
		if (jsonArray1.size() > 0) {
			jsonObject.set("children", jsonArray1);
		}
		jsonArray.add(jsonObject);
		return jsonArray;
	}

	// 人行单位整棵树的数据一次生成,加入缓存机制，只从数据库读取一次，其它从缓存中读取,url+?refresh=1可以激活重新读取数据库，刷新树形数据缓存
	@RequestMapping(value = "getallpbc", produces = MediaType.APPLICATION_JSON_VALUE)
	public @ResponseBody ArrayNode getallpbc(String id, String refresh) throws JsonProcessingException, IOException {
		if (pbcCache == null || refresh != null) {
			pbcCache = recurPbc(id);
		} else {
			System.out.println("从缓存中获得人行机构信息");
		}
		return pbcCache;
	}

	private ArrayNode recurPbc(String id) {
		ArrayNode jsonArray = objectMapper.createArrayNode();
		if (id == null)
			id = "A1000111000031";// 这是总行的id
		for (Jginfo Jginfo : getChildren(id)) {
			ObjectNode jsonObject = objectMapper.createObjectNode();
			String id0 = Jginfo.getJgId();
			jsonObject.set("id", objectMapper.convertValue(id0, JsonNode.class));
			jsonObject.set("text", objectMapper.convertValue(Jginfo.getJgName(), JsonNode.class));
			jsonObject.set("state", objectMapper.convertValue(hasChildren(id0) ? "closed" : "open", JsonNode.class));
			if (hasChildren(id0)) {
				jsonObject.set("children", recurPbc(id0));
			}
			jsonArray.add(jsonObject);
		}
		// JsonNode jsonNode=objectMapper.readTree(new
		// File(this.getClass().getResource("/json/pbc.json").getPath()));
		return jsonArray;
	}

	@RequestMapping(value = "getmenu", produces = MediaType.APPLICATION_JSON_VALUE)
	public @ResponseBody JsonNode getmenu() throws JsonProcessingException, IOException {
		String power = operator.getPower();
		JsonNode jsonNode = objectMapper.readTree(new File(this.getClass().getResource("/json/menu.json").getPath()));
		Iterator<JsonNode> it0 = jsonNode.elements();
		String splitChar = "|";
		while (it0.hasNext()) {
			JsonNode n0 = it0.next();
			String[] privil=n0.path("level").asText().split(splitChar);
			if (!haspower(privil,power)){
				it0.remove();
			}else{
				Iterator<JsonNode> it1 = n0.path("children").elements();
				while (it1.hasNext()) {
					JsonNode n1 = it1.next();
					
					if (!haspower(n1.path("level").asText().split(splitChar),power)){
						it1.remove();
					}else{
						Iterator<JsonNode> it2 = n1.path("children").elements();
						while (it2.hasNext()){
							JsonNode n2 = it2.next();
							if (!haspower(n2.path("level").asText().split(splitChar),power)){
								it2.remove();
							}
						}
					}
				}
			}
		}
		/*while (it0.hasNext()) {
			JsonNode n0 = it0.next();
			if (n0.path("level").asInt() > power) {
				it0.remove();
			} else {
				Iterator<JsonNode> it1 = n0.path("children").elements();
				while (it1.hasNext()) {
					JsonNode n1 = it1.next();
					if (n1.path("level").asInt() > power) {
						it1.remove();
					}else{
						Iterator<JsonNode> it2 = n1.path("children").elements();
						while (it2.hasNext()){
							JsonNode n2 = it2.next();
							if (n2.path("level").asInt() > power) {
								it2.remove();
							}
						}
					}
				}
			}
		}*/
		return jsonNode;
	}
  private boolean haspower(String[] privils,String power)
  {
		for(int i=0;i<privils.length;i++)
		{
			if(power.contains(privils[i]))
				return true;
		}
	  return false;
  }
	// 获得两层，自己和儿子,只返回两层人行单位数据，为了实现管理员只管理本级和下级管理员
	@RequestMapping(value = "getmysonjrjg", produces = MediaType.APPLICATION_JSON_VALUE)
	public @ResponseBody ArrayNode getmysonjrjg() throws JsonProcessingException, IOException {
		ArrayNode jsonArray = objectMapper.createArrayNode();
		User op = operator.getUser();
		if (op == null)
			return jsonArray;
		String pbcid = op.getJgId();
		Query<Jginfo> q = this.getCurrentSession()
				.createQuery("from Jginfo where jgId='" + pbcid + "'", Jginfo.class).setCacheable(true);
		Jginfo pbcinfo = q.getSingleResult();
		ObjectNode jsonObject = objectMapper.createObjectNode();
		jsonObject.set("id", objectMapper.convertValue(pbcid, JsonNode.class));
		jsonObject.set("text", objectMapper.convertValue(pbcinfo.getJgName(), JsonNode.class));
		jsonObject.set("state", objectMapper.convertValue("open", JsonNode.class));
		ArrayNode jsonArray1 = objectMapper.createArrayNode();
		for (Jginfo Jginfo : getChildren2(pbcid)) {
			ObjectNode jo = objectMapper.createObjectNode();
			String id0 = Jginfo.getJgId();
			jo.set("id", objectMapper.convertValue(id0, JsonNode.class));
			jo.set("text", objectMapper.convertValue(Jginfo.getJgName(), JsonNode.class));
			jo.set("state", objectMapper.convertValue("open", JsonNode.class));
			jsonArray1.add(jo);
		}
		if (jsonArray1.size() > 0) {
			jsonObject.set("children", jsonArray1);
		}
		jsonArray.add(jsonObject);
		return jsonArray;
	}

	private List<Jginfo> getChildren2(String pbcid) {
		Query<Jginfo> q = this.getCurrentSession()
				.createQuery("from Jginfo where c1Id='C' and pbcId='" + pbcid + "'", Jginfo.class)
				.setCacheable(true);
		List<Jginfo> Jginfos = q.getResultList();
		return Jginfos;
	}
}
